package com.tengju.bff.interfaces.app.charge.facade;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.tengju.bff.interfaces.app.charge.assembler.MarketAssembler;
import com.tengju.bff.interfaces.app.charge.vo.*;
import com.tengju.bff.interfaces.app.user.vo.RangeVO;
import com.tengju.bff.interfaces.shared.AmountType;
import com.tengju.bff.interfaces.shared.AmountVO;
import com.tengju.bff.interfaces.shared.Formatter;
import com.tengju.bff.interfaces.shared.KVVO;
import com.tengju.data.domain.model.analysis.Row;
import com.tengju.data.domain.model.clickhouse.MoneyOutTypeEnum;
import com.tengju.data.domain.model.clickhouse.OdsBigDataAchievementBonusDiDRepository;
import com.tengju.data.domain.model.report.*;
import com.tengju.data.domain.model.service.AchievementBonusDateConfigService;
import com.tengju.data.domain.model.user.UserIdCode;
import com.tengju.data.domain.shared.CastUtil;
import com.tengju.data.domain.shared.DateUtil;
import com.tengju.data.domain.shared.Month;
import com.tengju.data.domain.shared.Year;
import com.tengju.user.domain.model.user.UserInfo;
import com.tengju.user.domain.model.user.UserInfoRepository;
import com.tengju.user.domain.service.RemoteUserService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author chenhang
 * @Date 2021/1/26
 */
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class MarketFacade {

    @Value("${redis.cache.switch}")
    public boolean cacheSwitch;

    private final AchievementBonusRepository achievementBonusRepository;
    private final UserInfoRepository userInfoRepository;
    private final RemoteUserService remoteUserService;
    private final OdsBigDataAchievementBonusDiDRepository odsBigDateAchievementBonusDiDRepository;
    private final AchievementBonusDateConfigService achievementBonusDateConfigService;
    private final Integer MARKET_LIMIT_USER = 6;

    public MonthMarketAnalysisVO analysis(UserIdCode idCode, Integer month) {
        MonthMarketAnalysisVO monthMarketAnalysisVO = new MonthMarketAnalysisVO();
        LocalDate monthDate = LocalDate.parse(month + "01", DateTimeFormatter.ofPattern("yyyyMMdd"));

        List<AchievementBonus> bonusList = achievementBonusRepository.find(monthDate,idCode);
        if (CollectionUtils.isEmpty(bonusList)) {
            return monthMarketAnalysisVO;
        }
        BigDecimal totalAchievement = BigDecimal.ZERO;
        BigDecimal totalBonus = BigDecimal.ZERO;
        List<MarketTypeVO> typeAnalysis = new ArrayList<>();
        for (AchievementBonus bonus : bonusList) {
            totalAchievement = totalAchievement.add(bonus.getAchievement());
            totalBonus = totalBonus.add(bonus.getProfit());
        }

        BigDecimal finalTotalAchievement = totalAchievement;
        typeAnalysis = bonusList.stream().filter(bonus -> !(bonus.getAchievement() == null || bonus.getAchievement().compareTo(BigDecimal.valueOf(100)) < 0))
                .map(bonus -> MarketAssembler.bonusToTypeVO(bonus, finalTotalAchievement)).collect(Collectors.toList());

        typeAnalysis = typeAnalysis.stream().sorted(Comparator.comparingDouble(v -> {
            return CastUtil.castDouble(CastUtil.castString(v.getMarketIndex().getAmount()));
        })).collect(Collectors.toList());
        Collections.reverse(typeAnalysis);

        totalAchievement = totalAchievement.compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : totalAchievement;
        totalBonus = totalBonus.compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : totalBonus;

        monthMarketAnalysisVO.setMarketIndex(new AmountVO(AmountType.INDEX,totalAchievement));
        monthMarketAnalysisVO.setAdIndex(new AmountVO(AmountType.INDEX,totalBonus));
        monthMarketAnalysisVO.setTypeAnalysis(typeAnalysis);
        List<MarketRateVO> rateAnalysis = getChildRate(idCode,month,totalAchievement);
        rateAnalysis = rateAnalysis.stream().limit(MARKET_LIMIT_USER).collect(Collectors.toList());
        monthMarketAnalysisVO.setRateAnalysis(rateAnalysis);
        return monthMarketAnalysisVO;
    }

    private List<MarketRateVO> getChildRate(UserIdCode idCode, Integer month, BigDecimal totalAchievement) {
        //202101之前的用户根据现有的关系链查询
        List<AchievementBonus> childrenBonusList = new ArrayList<>();
        if (month < 202101) {
            List<Long> blackChildIdCodeList = remoteUserService.listBlackChildIdCode(idCode.getValue());
            childrenBonusList = achievementBonusRepository.listByIdCodesAndMonth(month,blackChildIdCodeList);
        } else {
            LocalDate monthDate = LocalDate.parse(month + "01", DateTimeFormatter.ofPattern("yyyyMMdd"));
            childrenBonusList = achievementBonusRepository.findChild(monthDate,idCode);
        }
        if (CollectionUtils.isEmpty(childrenBonusList)) {
            return Collections.emptyList();
        }
        List<MarketRateVO> rateAnalysis = new ArrayList<>();
        Map<Long, List<AchievementBonus>> userBonusMap = childrenBonusList.stream()
                .collect(Collectors.groupingBy(v -> v.getIdCode().getValue()));
        ArrayList<Long> userIdCodeValues = new ArrayList(userBonusMap.keySet());
        List<com.tengju.user.domain.model.user.UserIdCode> idCodeList = userIdCodeValues.stream()
                .map(com.tengju.user.domain.model.user.UserIdCode::new)
                .collect(Collectors.toList());
        Map<Long,UserInfo> starUserMap = new HashMap<>();
        Map<Long,UserInfo> remoteUserMap = new HashMap<>();
        List<UserInfo> starUserInfos = userInfoRepository.batchGetUserInfo(idCodeList);
        List<UserInfo> remoteUserInfo = remoteUserService.getByIdList(idCodeList);
        if (!CollectionUtils.isEmpty(starUserInfos)) {
            starUserMap = starUserInfos.stream()
                    .collect(Collectors.toMap(k -> k.getIdCode().getValue(),v -> v,(v1,v2) -> v1));
        }
        if (!CollectionUtils.isEmpty(remoteUserInfo)) {
            remoteUserMap = remoteUserInfo.stream()
                    .collect(Collectors.toMap(k -> k.getIdCode().getValue(),v -> v,(v1,v2) -> v1));
        }
        Set<Map.Entry<Long, List<AchievementBonus>>> entries = userBonusMap.entrySet();
        for (Map.Entry<Long, List<AchievementBonus>> entry : entries) {
            Long idCodeValue = entry.getKey();
            List<AchievementBonus> userBonusList = entry.getValue();
            MarketRateVO marketRateVO = MarketAssembler.assemblerToRateVO(totalAchievement,userBonusList,starUserMap.get(idCodeValue),remoteUserMap.get(idCodeValue));
            rateAnalysis.add(marketRateVO);
        }
        List<MarketRateVO> collect = rateAnalysis.stream().sorted(Comparator.comparingDouble(v -> {
            return CastUtil.castDouble(CastUtil.castString(v.getMarketIndex().getAmount()));
        })).collect(Collectors.toList());
        Collections.reverse(collect);
        return collect;
    }


    public MonthMarketRateDetailVO rateDetail(UserIdCode idCode, Integer month) {
        MonthMarketRateDetailVO monthMarketRateDetailVO = new MonthMarketRateDetailVO();
        LocalDate monthDate = LocalDate.parse(month + "01", DateTimeFormatter.ofPattern("yyyyMMdd"));
        List<AchievementBonus> bonusList = achievementBonusRepository.find(monthDate,idCode);
        if (CollectionUtils.isEmpty(bonusList)) {
            return monthMarketRateDetailVO;
        }
        BigDecimal totalAchievement = BigDecimal.ZERO;
        for (AchievementBonus bonus : bonusList) {
            totalAchievement = totalAchievement.add(bonus.getAchievement());
        }
        totalAchievement = totalAchievement.compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : totalAchievement;
        monthMarketRateDetailVO.setTotal(new AmountVO(AmountType.INDEX,totalAchievement));
        List<MarketRateVO> rateAnalysis = getChildRate(idCode,month,totalAchievement);
        List<MarketRateVO> topRateAnalysis = rateAnalysis.stream().limit(MARKET_LIMIT_USER).collect(Collectors.toList());
        BigDecimal topSum = topRateAnalysis.stream().map(v -> (BigDecimal) v.getMarketIndex().getAmount())
                .reduce((v1, v2) -> v1.add(v2))
                .orElseGet(() -> BigDecimal.ZERO);
        BigDecimal left = totalAchievement.subtract(topSum);
        if (left.compareTo(BigDecimal.ZERO) > 0) {
            MarketRateVO marketRateVO = new MarketRateVO();
            marketRateVO.setName("其他");
            marketRateVO.setMarketIndex(new AmountVO(AmountType.INDEX,left));
            double rate = left.divide(totalAchievement,4, RoundingMode.HALF_DOWN).doubleValue();
            marketRateVO.setRate(new AmountVO(AmountType.PERCENT,rate).getValue());
            topRateAnalysis.add(marketRateVO);
        }
        monthMarketRateDetailVO.setList(topRateAnalysis);
        monthMarketRateDetailVO.setAllList(rateAnalysis);
        return monthMarketRateDetailVO;
    }

    /**
     * 市场指数月度各礼包占比
     */
    @Cacheable(value = "default_cache",
            keyGenerator = "redisCacheKeyGenerator",
            condition = "#root.target.cacheSwitch")
    public MonthMarketClassifyVO getMonthMarketAnalysis(String month,UserIdCode userIdCode) {
        MonthMarketClassifyVO monthMarketClassifyVO = new MonthMarketClassifyVO();
        Month currentMonth = new Month(CastUtil.castInt(month.replaceAll("-","")));
        String startDate = currentMonth.getStartDate().toString();
        String endDate = currentMonth.getEndDate().toString();


        // 所选月份结算周期配置
        LocalDate curDate = LocalDate.now();
        AchievementBonusDateConfig dateConfig =
                achievementBonusDateConfigService.queryByDateKeyOrDefault(month.replaceAll("-",""),curDate);
        startDate = (dateConfig == null || dateConfig.getStartDate() == null) ? startDate : dateConfig.getStartDate().toString();
        endDate = (dateConfig == null || dateConfig.getEndDate() == null) ? endDate : dateConfig.getEndDate().toString();


        // 各出货额类型市场指数占比
        List<Row> marketRow = odsBigDateAchievementBonusDiDRepository.getMonthMarketClassifyRatio(
                startDate,
                endDate,
                userIdCode);
        Map<Integer,BigDecimal> marketMap = marketRow.stream()
                .collect(Collectors.toMap(k -> CastUtil.castInt(k.getValue("money_out_type")),
                        v -> CastUtil.castBigDecimal(v.getValue("ratio")),(v1,v2) -> v1));

        // 获取最新更新时间
        Row row = odsBigDateAchievementBonusDiDRepository.getUpdateTime(userIdCode);
        Long timeStamp = row == null || row.getValue("updateTime") == null ? null : CastUtil.castLong(row.getValue("updateTime"));
        String updateTimeStr = timeStamp == null ? "" :
                DateUtil.formatLocalDateTime(DateUtil.DATE_TIME_MINUTE_FORMAT,DateUtil.parseByMilliSeconds(timeStamp));


        // 获取总的市场指数
        List<AchievementBonus> bonusList = achievementBonusRepository.find(currentMonth.getRandomDate(),userIdCode);

        BigDecimal marketTotal = bonusList.stream()
                .filter(Objects::nonNull)
                .map(v -> CastUtil.castBigDecimal(v.getAchievement()))
                .reduce(BigDecimal::add)
                .orElse(BigDecimal.ZERO);

        List<KVVO> marketIndex = Lists.newArrayList();

        for (MoneyOutTypeEnum typeEnum : MoneyOutTypeEnum.values()) {
            // 对应类型市场指数
            BigDecimal moneyOut = marketMap.get(typeEnum.getCode()) == null ? BigDecimal.ZERO :
                    marketMap.get(typeEnum.getCode()).multiply(marketTotal);
            marketIndex.add(KVVO.of(
                    typeEnum.getDesc(),
                    Formatter.formatIndex(moneyOut.intValue()),
                    Formatter.percentOfObj(marketMap.get(typeEnum.getCode()),2)
                    ));
        }

        monthMarketClassifyVO.setUpdateTime(updateTimeStr);
        monthMarketClassifyVO.setList(marketIndex);

        return monthMarketClassifyVO;

    }

    /**
     * 广告指数月度各礼包占比
     */
    @Cacheable(value = "default_cache",
            keyGenerator = "redisCacheKeyGenerator",
            condition = "#root.target.cacheSwitch")
    public MonthMarketClassifyVO getMonthAdvertiseAnalysis(String month,UserIdCode userIdCode) {
        MonthMarketClassifyVO monthMarketClassifyVO = new MonthMarketClassifyVO();
        Month currentMonth = new Month(CastUtil.castInt(month.replaceAll("-","")));
        String startDate = currentMonth.getStartDate().toString();
        String endDate = currentMonth.getEndDate().toString();


        // 所选月份结算周期配置
        LocalDate curDate = LocalDate.now();
        AchievementBonusDateConfig dateConfig =
                achievementBonusDateConfigService.queryByDateKeyOrDefault(month.replaceAll("-",""),curDate);
        startDate = (dateConfig == null || dateConfig.getStartDate() == null) ? startDate : dateConfig.getStartDate().toString();
        endDate = (dateConfig == null || dateConfig.getEndDate() == null) ? endDate : dateConfig.getEndDate().toString();
        // 各出货额类型中各商品类型市场指数
        List<Row> marketRow = odsBigDateAchievementBonusDiDRepository.getIndexByTeamRatioType(
                startDate,
                endDate,
                userIdCode);

        // 各商品类型广告指数
        List<Row> adRow =
                achievementBonusRepository.getAchievementByTeamRatioType(userIdCode,currentMonth.getMonthInt());

        // 每一个商品类型广告指数、所有类型广告指数总和
        BigDecimal adTotal = BigDecimal.ZERO;
        Map<Integer,BigDecimal> adTeamRatioTypeTotalMap = new HashMap<>();
        for (Row row : adRow) {
            int teamRatioType = CastUtil.castInt(row.getValue("team_ratio_type"));
            BigDecimal profit = CastUtil.castBigDecimal(row.getValue("profit"));
            adTeamRatioTypeTotalMap.put(teamRatioType,profit);
            adTotal = adTotal.add(profit);
        }

        // 各出货额类型中所有商品类型
        Map<Integer,Map<Integer,BigDecimal>> marketAllMap = Maps.newHashMap();
        Map<Integer,BigDecimal> teamRatioTypeTotalMap = new HashMap<>();
        for (Row row : marketRow) {
            int moneyOutType = CastUtil.castInt(row.getValue("money_out_type"));
            int teamRatioType = CastUtil.castInt(row.getValue("team_ratio_type"));
            Map<Integer, BigDecimal> moneyOutTypeMap = marketAllMap.getOrDefault(moneyOutType,new HashMap<>());
            BigDecimal moneyOut = CastUtil.castBigDecimal(row.getValue("money_out"));
            moneyOutTypeMap.put(teamRatioType,moneyOut);
            marketAllMap.put(moneyOutType,moneyOutTypeMap);
            // 每一类商品类型总和
            BigDecimal teamRatioTypeTotal = teamRatioTypeTotalMap.getOrDefault(teamRatioType, BigDecimal.ZERO);
            teamRatioTypeTotal = teamRatioTypeTotal.add(moneyOut);
            teamRatioTypeTotalMap.put(teamRatioType,teamRatioTypeTotal);
        }

        List<KVVO> adIndex = Lists.newArrayList();
        for (MoneyOutTypeEnum outTypeEnum : MoneyOutTypeEnum.values()) {
            // 一个出货额类型中所有商品类型市场指数
            Map<Integer, BigDecimal> teamRatioTypeMap = marketAllMap.getOrDefault(outTypeEnum.getCode(), Maps.newHashMap());

            BigDecimal moneyOutTypeVal = BigDecimal.ZERO;
            for (Map.Entry<Integer,BigDecimal> entry : teamRatioTypeMap.entrySet()) {
                Integer teamRatioType = entry.getKey();
                BigDecimal adTeamRatioTypeTotal = adTeamRatioTypeTotalMap.getOrDefault(entry.getKey(),BigDecimal.ZERO);
                BigDecimal achievementTeamRatioType = entry.getValue();
                BigDecimal achievementTeamRatioTypeTotal = teamRatioTypeTotalMap.getOrDefault(teamRatioType, BigDecimal.ZERO);
                BigDecimal adTeamRatioTypeVal = BigDecimal.ZERO;

                // 广告指数 = （市场指数 * 总广告指数） / 总市场指数   指定team_ratio_type
                if (achievementTeamRatioTypeTotal.compareTo(BigDecimal.ZERO) > 0) {
                    adTeamRatioTypeVal = adTeamRatioTypeTotal.multiply(achievementTeamRatioType).divide(achievementTeamRatioTypeTotal,4,RoundingMode.DOWN);
                }

                //把所有team_ratio_type类型的广告指数相加，得到某一出货额类型的广告指数
                moneyOutTypeVal = moneyOutTypeVal.add(adTeamRatioTypeVal);
            }
            // money_out_type类型广告指数占比
            BigDecimal adRatio = BigDecimal.ZERO;
            if (adTotal.compareTo(BigDecimal.ZERO) > 0) {
                adRatio = moneyOutTypeVal.divide(adTotal,4,RoundingMode.DOWN);
            }

            adIndex.add(KVVO.of(
                    outTypeEnum.getDesc(),
                    Formatter.formatIndex(moneyOutTypeVal.intValue()),
                    Formatter.percentOfObj(adRatio,2)
            ));

        }

        // 获取最新更新时间
        Row row = odsBigDateAchievementBonusDiDRepository.getUpdateTime(userIdCode);
        Long timeStamp = row == null || row.getValue("updateTime") == null ? null : CastUtil.castLong(row.getValue("updateTime"));
        String updateTimeStr = timeStamp == null ? "" :
                DateUtil.formatLocalDateTime(DateUtil.DATE_TIME_MINUTE_FORMAT,DateUtil.parseByMilliSeconds(timeStamp));

        monthMarketClassifyVO.setUpdateTime(updateTimeStr);
        monthMarketClassifyVO.setList(adIndex);
        return monthMarketClassifyVO;

    }


    /**
     * 市场指数趋势图（天维度）
     */
    @Cacheable(value = "default_cache",
            keyGenerator = "redisCacheKeyGenerator",
            condition = "#root.target.cacheSwitch")
    public List<RangeVO> getMonthDateMarketTendency(String month,UserIdCode userIdCode) {
        Integer monthInt = CastUtil.castInt(month.replaceAll("-",""));
        Month currentMonth = new Month(monthInt);
        List<Row> rowList = odsBigDateAchievementBonusDiDRepository.getMonthDateMarketTendency(
                currentMonth.getStartDate().toString(),
                currentMonth.getEndDate().toString(),
                userIdCode);
        Map<String,BigDecimal> map = rowList.stream()
                .collect(Collectors.toMap(k -> CastUtil.castString(k.getValue("visit_date")),
                        v -> CastUtil.castBigDecimal(v.getValue("money_out")),
                        (v1,v2) -> v1));
        // 填充当前月每天数据
        List<RangeVO> rangeVOList = Lists.newArrayList();
        LocalDate ld = currentMonth.getStartDate();
        for (int i = 0; i < ld.lengthOfMonth(); i++) {
            LocalDate date = ld.plusDays(i);
            rangeVOList.add(new RangeVO(String.valueOf(String.format("%s日",date.getDayOfMonth())),
                    String.valueOf(map.get(date.toString()) == null ? String.valueOf(0) : map.get(date.toString())))
            );
        }

        return rangeVOList;
    }


    /**
     * 月每天市场指数详情
     */
    @Cacheable(value = "default_cache",
            keyGenerator = "redisCacheKeyGenerator",
            condition = "#root.target.cacheSwitch")
    public List<DateMarketClassifyVO> getMonthDateMarketDetail(String month,UserIdCode userIdCode) {
        Integer monthInt = CastUtil.castInt(month.replaceAll("-",""));
        Month currentMonth = new Month(monthInt);
        List<Row> rowList = odsBigDateAchievementBonusDiDRepository.
                getMonthDateMarketDetail(
                currentMonth.getStartDate().toString(),
                currentMonth.getEndDate().toString(),
                userIdCode);
        // 每一天的数据分组
        Map<String,List<Row>> visitDateMap = Maps.newHashMap();
        Map<String,BigDecimal> totalMap = Maps.newHashMap();
        for (Row row : rowList) {
            String visitDate = CastUtil.castString(row.getValue("visit_date"));
            List<Row> visitDateList = visitDateMap.getOrDefault(visitDate, new ArrayList<>());
            if (CollectionUtils.isEmpty(visitDateList)) {
                visitDateList = new ArrayList<>();
            }
            visitDateList.add(row);
            visitDateMap.put(visitDate,visitDateList);
            BigDecimal total = totalMap.getOrDefault(visitDate, BigDecimal.ZERO);
            total = total.add(BigDecimal.valueOf(CastUtil.castDouble(row.getValue("money_out"))));
            totalMap.put(visitDate,total);
        }

        List<DateMarketClassifyVO> dateMarketClassifyVOList = Lists.newArrayList();
        LocalDate monthStartDate = currentMonth.getStartDate();
        LocalDate currentDate = LocalDate.now();
        int length = monthStartDate.lengthOfMonth();
        if ((new Month(monthStartDate).getMonthInt()).equals(new Month(currentDate).getMonthInt())) {
            length = currentDate.getDayOfMonth();
        }
        // 只显示到当前日期数据
        for (int i = 0; i < length; i++) {
            DateMarketClassifyVO vo = new DateMarketClassifyVO();
            // 每天各出货额类型
            String visitDate = monthStartDate.plusDays(i).toString();

            vo.setVisitDate(visitDate);
            vo.setTotal(Formatter.formatIndex(totalMap.getOrDefault(visitDate,BigDecimal.ZERO).intValue()));

            List<KVVO> outTypeList = Lists.newArrayList();

            List<Row> visitDateList = visitDateMap.getOrDefault(visitDate,new ArrayList<>());
            Map<Integer, Row> moneyOutTypeMap = visitDateList.stream()
                    .filter(Objects::nonNull)
                    .collect(Collectors.toMap(k -> CastUtil.castInt(
                            k.getValue("money_out_type")),
                            v -> v,
                            (v1, v2) -> v2));

            for (MoneyOutTypeEnum typeEnum : MoneyOutTypeEnum.values()) {
                Row row = moneyOutTypeMap.get(typeEnum.getCode());
                BigDecimal typeVal = BigDecimal.ZERO;
                BigDecimal total = totalMap.getOrDefault(visitDate,BigDecimal.ZERO);
                if (row != null) {
                    typeVal = CastUtil.castBigDecimal(row.getValue("money_out"));
                }
                BigDecimal percent = BigDecimal.ZERO;
                if (total.compareTo(BigDecimal.ZERO) > 0) {
                    percent = typeVal.divide(total,4, RoundingMode.DOWN);
                }
                outTypeList.add(KVVO.of(
                        typeEnum.getDesc(),
                        Formatter.formatIndex(typeVal.intValue()),
                        Formatter.percentOfObj(percent,2)
                ));
            }

            vo.setMarketIndex(outTypeList);
            dateMarketClassifyVOList.add(vo);
        }
        // 时间倒序
        dateMarketClassifyVOList.sort(Comparator.comparing(DateMarketClassifyVO::getVisitDate).reversed());

        return dateMarketClassifyVOList;
    }


    public RangeLineVO getYearMonthMarketTendency(String year,UserIdCode userIdCode) {
        RangeLineVO rangeLineVO = new RangeLineVO();
        Year currentYear = new Year(year);
        List<AchievementBonusSum> achievementBonusSumList =
                achievementBonusRepository.getAchievementByYear(userIdCode,currentYear);
        Map<Integer,AchievementBonusSum> map = achievementBonusSumList.stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toMap(AchievementBonusSum::getMonth, v -> v,(v1, v2) -> v1));
        // 年总数
        Long total = achievementBonusSumList.stream()
                .filter(Objects::nonNull)
                .mapToLong(v -> v.getAchievement().longValue())
                .sum();
        // 填充每月数据
        List<RangeVO> rangeVOList = Lists.newArrayList();
        for (int i = 0; i < 12; i++) {
            Integer monthInt = new Month(currentYear.getYearStartDate().plusMonths(i)).getMonthInt();
            rangeVOList.add(new RangeVO(String.format("%s月",currentYear.getYearStartDate().plusMonths(i).getMonthValue()),
                    map.get(monthInt) == null || map.get(monthInt).getAchievement() == null ? String.valueOf(0) :
                            String.valueOf(map.get(monthInt).getAchievement()))
            );

        }
        rangeLineVO.setTotal(String.valueOf(total));
        rangeLineVO.setList(rangeVOList);


        return rangeLineVO;
    }

    /**
     * 结算周期提示
     */
    public KVVO getIndexSettleCycleHint(String month) {
        Month originMonth = new Month(CastUtil.castInt(month.replaceAll("-","")));
        LocalDate curDate = LocalDate.now();
        LocalDate startDate = originMonth.getStartDate();
        LocalDate endDate = originMonth.getEndDate();

        AchievementBonusDateConfig dateConfig =
                achievementBonusDateConfigService.queryByDateKeyOrDefault(month.replaceAll("-", ""), curDate);

        startDate = (dateConfig == null || dateConfig.getStartDate() == null) ? startDate : dateConfig.getStartDate();
        endDate = (dateConfig == null || dateConfig.getEndDate() == null) ? endDate : dateConfig.getEndDate();

        return KVVO.of("结算周期文案提示",
                String.format("温馨提示:%s月结算周期为%s至%s",
                        originMonth.getRandomDate().getMonthValue(),
                        startDate.format(DateTimeFormatter.ofPattern("MM月dd日00:00")),
                        endDate.format(DateTimeFormatter.ofPattern("MM月dd日24:00"))
                        )
                );
    }



}
